package com.black.utils.file.compress.jar.visitor;

import com.black.utils.file.compress.jar.entity.AnnotationInfo;
import com.black.utils.file.compress.jar.entity.ClassInfo;
import com.black.utils.file.compress.jar.entity.FieldInfo;
import com.black.utils.file.compress.jar.entity.MethodInfo;
import lombok.Getter;
import org.objectweb.asm.*;

/**
 * @author ylx
 */
@Getter
public class JarClassVisitor extends ClassVisitor implements Opcodes {
    private ClassInfo classInfo;

    public JarClassVisitor() {
        super(ASM7);
    }

    /**
     * 初始化类信息
     * 该方法在类加载时被调用，用于设置类的基本信息
     *
     * @param version    类文件的版本号，用于区分不同版本的类文件
     * @param access     类的访问权限，如public、abstract等
     * @param name       类的全限定名
     * @param signature  类的签名，用于描述类的泛型信息
     * @param superName  类的父类名称
     * @param interfaces 类实现的接口列表
     */
    @Override
    public void visit(int version, int access, String name, String signature, String superName, String[] interfaces) {
        classInfo = new ClassInfo(version, access, name, signature, superName, interfaces);
    }

    // TODO 内部类访问

    /**
     * 当类访问它的方法时，此方法被调用，用于处理访问到的每个方法
     *
     * @param access     方法的访问标志，表示方法的访问级别（如public、private等）
     * @param name       方法名
     * @param desc       方法的描述，包括参数类型和返回类型
     * @param signature  方法的签名，对于泛型方法，此参数非null
     * @param exceptions 方法可能抛出的异常列表
     * @return 返回一个MethodVisitor对象，用于继续访问方法内的细节
     */
    @Override
    public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions) {
        // 创建MethodInfo对象，用于存储方法的相关信息
        MethodInfo methodInfo = new MethodInfo(access, name, desc, signature, exceptions);
        // 将新创建的方法信息对象添加到类信息中
        classInfo.addMethod(name, desc, methodInfo);
        return new JarMethodVisitor(methodInfo);
    }

    /**
     * 访问类中的一个字段时调用此方法
     * 该方法的作用是创建字段信息，并将其添加到类信息中
     * 同时返回一个新的字段访问器，用于实际字段的访问
     *
     * @param access    字段的访问权限
     * @param name      字段的名称
     * @param desc      字段的描述，如类型等
     * @param signature 字段的签名，用于泛型等复杂类型描述
     * @param value     字段的默认值
     * @return 返回一个新的字段访问器，用于实际字段的访问
     */
    @Override
    public FieldVisitor visitField(int access, String name, String desc, String signature, Object value) {
        // 创建一个新的字段信息对象，用于存储字段的相关信息
        FieldInfo fieldInfo = new FieldInfo(access, name, desc, signature, value);
        // 将字段信息添加到类信息中，以便后续使用
        classInfo.addField(name, fieldInfo);
        // 返回一个新的字段访问器，用于实际字段的访问
        return new JarFieldVisitor(fieldInfo);
    }


    /**
     * 访问类中的注解
     *
     * @param desc    注解的描述信息，用于标识注解类型
     * @param visible 注解的可见性，表示注解是否在运行时可见
     * @return 返回一个AnnotationVisitor对象，用于后续访问注解的元素
     */
    @Override
    public AnnotationVisitor visitAnnotation(String desc, boolean visible) {
        // 创建一个JarAnnotationVisitor对象，用于处理注解信息
        AnnotationInfo annotationInfo = new AnnotationInfo(desc);
        classInfo.addAnnotation(desc, annotationInfo);
        return new JarAnnotationVisitor(annotationInfo);
    }


}
